<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- 
        计算属性
            概念：
                一个依赖与其他响应式数据的一个数据，可以象其他数据一样去使用。但是不能直接修改。

            何时使用：
                当你需要一个数据，该数据可以由现有的数据计算或者推导得到，那么该数据就可以做成一个计算属性

            不能直接修改：
                会报错，因为它是只读的。

                如果一定要改，有没有方法，也有，方式就是声明该计算属性时使用对象写法


     -->

    <div id="app">
        <button @click="first+='~'">First: {{ first }}</button>
        <button @click="last+='!'">Last: {{ last }}</button>
        <button @click="msg = msg.substr(0, msg.length - 1)">Msg: {{ msg }}</button>

        <hr />
        <!-- 模板中直接做逻辑 -->
        <p>FullName: {{ first + '' + last }}</p>
        <!-- 将逻辑做到计算属性中，然后使用计算属性 -->
        <p>FullName: {{ fullName }}</p>

        <hr />
        <p>反转Msg: {{ msg.split('').reverse().join('') }}</p>
        <p>反转Msg: {{ reverseMsg }}</p>

        <hr />
        <button @click="handleChangeFullName">修改 fullName</button>
        <button @click="handleChangeReverseMsg">修改 reverseMsg</button>
    </div>

    <script type="module">
        import { createApp } from './lib/vue3.esm.browser.js'


        createApp({

            data() {
                return {
                    first: '张',
                    last: '三',

                    msg: 'Hello'
                }
            },

            computed: {
                /**
                 * 一、一个getter函数语法
                 */
                // fullName() {
                //     return this.first + '' + this.last
                // },

                fullName: {
                    get() {
                        return this.first + '' + this.last
                    },

                    // this.fullName = '里斯'
                    set(value) {
                        this.first = value.split('')[0]
                        this.last = value.split('')[1]
                    }
                },

                /**
                 * 二、一个对象的语法
                 *      get         getter 函数
                 *      set         setter 函数
                 */
                reverseMsg: {
                    get() {
                        console.log('get')
                        return this.msg.split('').reverse().join('')
                    },
                    // this.reverseMsg = 'World'
                    set(value) {
                        // 给计算属性提供了 setter 函数之后，修改该计算属性不会报错，而是触发了该 setter

                        // 会发现还是不能直接修改掉计算属性，只能去修改它的依赖数据，然后依赖数据的变化再引起该计算属性的 getter 
                        // 重新执行，间接的去修改计算属性。
                        console.log('set', value)

                        this.msg = value.split('').reverse().join('')
                    }
                }
            },

            methods: {
                handleChangeFullName() {
                    console.log('fullName', this.fullName)

                    // 尝试修改
                    this.fullName = '里斯'
                },

                handleChangeReverseMsg() {
                    this.reverseMsg = 'World'
                }
            }

        }).mount('#app')
    </script>
</body>

</html>